<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">

<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&display=swap&subset=latin,latin-ext">
<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"yoursite.com","root":"/","scheme":"Pisces","version":"7.7.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="Spring框架1">
<meta property="og:type" content="article">
<meta property="og:title" content="Java日拱一卒-day22">
<meta property="og:url" content="http://yoursite.com/2020/05/30/Java%E6%97%A5%E6%8B%B1%E4%B8%80%E5%8D%92-day22/index.html">
<meta property="og:site_name" content="很惭愧，就做了一点微小的工作">
<meta property="og:description" content="Spring框架1">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://yoursite.com/2020/05/30/Java%E6%97%A5%E6%8B%B1%E4%B8%80%E5%8D%92-day22/Spring.png">
<meta property="og:image" content="http://yoursite.com/2020/05/30/Java%E6%97%A5%E6%8B%B1%E4%B8%80%E5%8D%92-day22/IOC.png">
<meta property="article:published_time" content="2020-05-29T16:09:02.000Z">
<meta property="article:modified_time" content="2020-07-06T15:55:33.611Z">
<meta property="article:author" content="文予">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://yoursite.com/2020/05/30/Java%E6%97%A5%E6%8B%B1%E4%B8%80%E5%8D%92-day22/Spring.png">

<link rel="canonical" href="http://yoursite.com/2020/05/30/Java%E6%97%A5%E6%8B%B1%E4%B8%80%E5%8D%92-day22/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>Java日拱一卒-day22 | 很惭愧，就做了一点微小的工作</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">很惭愧，就做了一点微小的工作</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">念念不忘，必有回响</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-fw fa-home"></i>首页</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>归档</a>

  </li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div id="search-result">
  <div id="no-result">
    <i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>
  </div>
</div>

    </div>
  </div>

</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2020/05/30/Java%E6%97%A5%E6%8B%B1%E4%B8%80%E5%8D%92-day22/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/uploads/wenyu.png">
      <meta itemprop="name" content="文予">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="很惭愧，就做了一点微小的工作">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          Java日拱一卒-day22
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2020-05-30 00:09:02" itemprop="dateCreated datePublished" datetime="2020-05-30T00:09:02+08:00">2020-05-30</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2020-07-06 23:55:33" itemprop="dateModified" datetime="2020-07-06T23:55:33+08:00">2020-07-06</time>
              </span>

          
            <div class="post-description">Spring框架1</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h2 id="Spring简介"><a href="#Spring简介" class="headerlink" title="Spring简介"></a>Spring简介</h2><p>Spring是分层的JavaSE及JavaEE应用于全栈的轻量级开源框架，以<code>IoC</code>(Inverse of Control:控制反转)和<code>AOP</code>(Aspact Oriented Programming:面向切面编程)为核心，提供了表现层<code>SpringMVC</code>和持久层<code>Spring JDBC</code>以及业务层事务管理等众多模块的企业级应用技术。</p>
<p>Spring的本质是管理软件中的对象，即创建对象与维护对象之间的关系</p>
<h3 id="Spring的优势"><a href="#Spring的优势" class="headerlink" title="Spring的优势"></a>Spring的优势</h3><ul>
<li><ol>
<li>方便解耦、简化开发</li>
</ol>
</li>
</ul>
<p>通过Spring提供的<code>IoC</code>容器，可以将对象间的依赖关系交由Spring进行控制，避免硬编码所造成的过度程序耦合。用户也不必再为较为底层的需求编写代码，可以更专注于上层的应用。</p>
<ul>
<li><ol start="2">
<li>AOP编程的支持</li>
</ol>
</li>
</ul>
<p>通过Spring的AOP功能，方便进行面向切面的编程，许多不容易用传统面向对象编程实现的功能可以通过AOP轻松应付</p>
<ul>
<li><ol start="3">
<li>声明式事务的支持</li>
</ol>
</li>
</ul>
<p>可以将开发者从单调的事务管理代码中解脱出来，通过声明式方式灵活的进行事务的管理，提高开发效率与质量</p>
<ul>
<li><ol start="4">
<li>方便程序的测试</li>
</ol>
</li>
</ul>
<p>可以用非容器依赖的编程方式进行几乎所有的测试工作，测试变成了随手可做的事情</p>
<ul>
<li><ol start="5">
<li>方便集成各种优秀框架</li>
</ol>
</li>
</ul>
<p>Spring可以降低各种框架的使用难度，提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。</p>
<ul>
<li><ol start="6">
<li>降低JavaEE API的使用难度</li>
</ol>
</li>
</ul>
<p>Spring对JavaEE API进行了薄薄的封装层，使得这些API的使用难度大大降低</p>
<ul>
<li><ol start="7">
<li>Spring框架的源码的经典的学习范例</li>
</ol>
</li>
</ul>
<p>Spring的源代码设计精妙、结构清晰、匠心独用，处处体现着大师对Java设计模式灵活运用以及对 Java技术的高深造诣。它的源代码无疑是Java技术的最佳实践的范例。</p>
<h3 id="Spring的架构"><a href="#Spring的架构" class="headerlink" title="Spring的架构"></a>Spring的架构</h3><p>Spring的最初目标是整合一切优秀资源，然后对外提供一个统一的服务。Spring模块构建在核心容器之上，核心容器定义了创建、配置和管理bean的方式，如图所示：</p>
<p><img src="/2020/05/30/Java%E6%97%A5%E6%8B%B1%E4%B8%80%E5%8D%92-day22/Spring.png" alt="Spring"></p>
<p>组成Spring框架的每个模块（或组件）都可以单独存在，或者与其他一个或多个模块联合实现，每个模块的功能如下：</p>
<table>
<thead>
<tr>
<th align="center">模块</th>
<th align="center">说明</th>
</tr>
</thead>
<tbody><tr>
<td align="center">核心容器Spring Core</td>
<td align="center">核心容器，提供Spring框架的基本功能。核心容器的主要组件是BeanFactory，它是工厂模式的实现。BeanFactory 使用控制反转（IOC）模式，将应用程序的配置和依赖性规范与实际的应用程序代码分开。</td>
</tr>
<tr>
<td align="center">Spring Context</td>
<td align="center">Spring上下文，是一个配置文件，向 Spring 框架提供上下文信息。Spring 上下文包括企业服务，例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。</td>
</tr>
<tr>
<td align="center">Spring AOP</td>
<td align="center">通过配置管理特性，Spring AOP 模块直接将面向切面的编程功能集成到了 Spring 框架中。可以很容易地使 Spring框架管理的任何对象支持AOP。Spring AOP模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP，就可以将声明性事务管理集成到应用程序中。</td>
</tr>
<tr>
<td align="center">Spring DAO</td>
<td align="center">JDBC DAO 抽象层提供了有意义的异常层次结构，可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理，并且极大地降低了需要编写的异常代码数量（例如打开和关闭连接）。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。</td>
</tr>
<tr>
<td align="center">Spring ORM</td>
<td align="center">Spring 框架插入了若干个 ORM 框架，从而提供了 ORM 的对象关系工具，其中包括JDO、Hibernate和iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。</td>
</tr>
<tr>
<td align="center">Spring Web</td>
<td align="center">Web上下文模块建立在应用程序上下文模块之上，为基于 Web 的应用程序提供了上下文。所以Spring 框架支持与 Jakarta Struts的集成。Web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。</td>
</tr>
<tr>
<td align="center">Spring MVC框架</td>
<td align="center">MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口，MVC 框架变成为高度可配置的，MVC 容纳了大量视图技术，其中包括 JSP、Velocity、Tiles、iText 和 POI。</td>
</tr>
</tbody></table>
<h2 id="程序中的耦合与解耦"><a href="#程序中的耦合与解耦" class="headerlink" title="程序中的耦合与解耦"></a>程序中的耦合与解耦</h2><h3 id="什么是程序的耦合"><a href="#什么是程序的耦合" class="headerlink" title="什么是程序的耦合"></a>什么是程序的耦合</h3><p>耦合性是对模块间关联程度的度量。耦合的强弱取决于模块间接口的复杂性、调用模块的方式以及通过界面传送的数据的多少。模块间的耦合度是指模块之间的依赖关系。模块间联系越多，耦合性越强，同时独立性越差。降低程序之间的依赖程度，即降低程序之间的耦合度的过程就叫解耦。</p>
<p>例如在JDBC操作中，注册数据库驱动时，一般采用<code>Class.forName</code>的方式，而不是<code>DriverManager.registerDriver</code>的方式</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestJdbc</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>&#123;</span><br><span class="line">    <span class="comment">//1.注册数据库驱动</span></span><br><span class="line">    <span class="comment">// DriverManager.registerDriver( new Driver() );</span></span><br><span class="line">    Class.forName(<span class="string">"com.mysql.jdbc.Driver"</span>);</span><br><span class="line">    <span class="comment">//2.获取数据库连接</span></span><br><span class="line">    <span class="comment">//3.获取传输器</span></span><br><span class="line">    <span class="comment">//4.发送sql到服务器执行并返回执行结果</span></span><br><span class="line">    <span class="comment">//5.处理结果</span></span><br><span class="line">    <span class="comment">//6.释放资源</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>除了<code>DriverManager.registerDriver</code>会导致驱动注册两次外，更重要的是，如果使用这种方式，JDBC程序就会依赖于数据库的驱动类（MySQL的Driver类），如果后期程序因数据量和性能原因升级到Oracle数据库，就需要修改程序源代码，重新导入新的驱动类，会增加很多不必要的麻烦。</p>
<p>使用<code>Class.forName</code>的方式注册驱动，好处是JDBC程序不再依赖具体的驱动类，即使不导入MySQL驱动包，程序依然可以编译。</p>
<p>此时类中只是将MySQL驱动类的全限定类名写死在程序中，可以将这个字符串提取到配置文件中，后期可以通过修改配置文件的方法轻松替换数据库产品。</p>
<h3 id="工厂模式解耦示例"><a href="#工厂模式解耦示例" class="headerlink" title="工厂模式解耦示例"></a>工厂模式解耦示例</h3><p>在实际开发中可以将三层（表现层、业务层、持久层）的对象都使用配置文件配置起来，当启动服务器加载应用时，可以通过工厂读取配置文件，根据配置文件中的配置将这些对象创建出来，在接下来使用的时候，直接使用即可。</p>
<p>简要步骤如下：</p>
<ul>
<li><ol>
<li>创建一个Maven的Java工程</li>
</ol>
</li>
<li><ol start="2">
<li><p>常见持久层接口和接口实现类</p>
<blockquote>
<p><code>com.tedu.dao.EmpDao</code>（接口）<br><code>com.tedu.dao.EmpDaoImpl</code>（实现类）</p>
</blockquote>
</li>
</ol>
</li>
<li><ol start="3">
<li>创建业务层接口和接口实现类<blockquote>
<p><code>com.tedu.service.EmpService</code> （接口）<br><code>com.tedu.service.EmpServiceImpl</code>（实现类）</p>
</blockquote>
</li>
</ol>
</li>
<li><ol start="4">
<li>创建表现层测试程序<code>com.tedu.controller.EmpController</code>并运行测试程序</li>
</ol>
</li>
<li><ol start="5">
<li><p>通过工程+配置文件+接口（已有）方式解耦</p>
<blockquote>
<p>(1)创建工厂类（com.tedu.factory.BeanFactory）并实现</p>
<p>(2)提供配置文件，将service接口和dao接口的实现类的全限定类名编写到配置文件中</p>
</blockquote>
</li>
</ol>
</li>
<li><ol start="6">
<li>使用工厂获取service接口和dao接口的实例，替换使用new的方式获取接口的实例</li>
</ol>
</li>
</ul>
<p>详细代码如下：</p>
<ul>
<li><ol>
<li>创建持久层接口（com.tedu.dao.EmpDao）</li>
</ol>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.tedu.dao;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 员工模块的Dao(持久层)接口</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">EmpDao</span> </span>&#123;</span><br><span class="line">    <span class="comment">/** 添加员工信息 */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addEmp</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><ol start="2">
<li>创建持久层接口实现类（com.tedu.dao.EmpDaoImpl）</li>
</ol>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.tedu.dao;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 员工模块的Dao(持久层)接口实现类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">EmpDaoImpl</span> <span class="keyword">implements</span> <span class="title">EmpDao</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addEmp</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(</span><br><span class="line">            <span class="string">"Dao层的addEmp()方法执行了..成功保存了一条员工信息.."</span></span><br><span class="line">        );</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><ol start="3">
<li>创建业务层接口（com.tedu.service.EmpService）</li>
</ol>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.tedu.service;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 员工模块的service(业务层)接口</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">interface</span> <span class="title">EmpService</span> </span>&#123;</span><br><span class="line">    <span class="comment">/** 添加员工信息 */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addEmp</span><span class="params">()</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><ol start="4">
<li>创建业务层接口实现类（com.tedu.service.EmpServiceImpl）</li>
</ol>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.tedu.service;</span><br><span class="line"><span class="keyword">import</span> com.tedu.dao.EmpDao;</span><br><span class="line"><span class="keyword">import</span> com.tedu.dao.EmpDaoImpl;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 员工模块的service(业务层)接口实现类</span></span><br><span class="line"><span class="comment"> * service层 ---&gt; dao层</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">EmpServiceImpl</span> <span class="keyword">implements</span> <span class="title">EmpService</span> </span>&#123;</span><br><span class="line">    <span class="comment">/* 获取Dao接口的子类实例</span></span><br><span class="line"><span class="comment">     * ——这里使用new对象的方式造成了程序之间的耦合性提升 */</span></span><br><span class="line">    <span class="keyword">private</span> EmpDao dao = <span class="keyword">new</span> EmpDaoImpl();</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addEmp</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"调用dao层的方法添加员工信息..."</span>);</span><br><span class="line">        dao.addEmp();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><ol start="5">
<li>创建表现层测试类（com.tedu.controller.EmpController）</li>
</ol>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.tedu.controller;</span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> com.tedu.service.EmpService;</span><br><span class="line"><span class="keyword">import</span> com.tedu.service.EmpServiceImpl;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 模拟表现层</span></span><br><span class="line"><span class="comment"> * controller --&gt; service --&gt; dao</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">EmpController</span> </span>&#123;</span><br><span class="line">    <span class="comment">/* 获取Service接口的子类实例</span></span><br><span class="line"><span class="comment">     * ——这里使用new对象的方式造成了程序之间的耦合性提升 */</span></span><br><span class="line">    <span class="keyword">private</span> EmpService service = <span class="keyword">new</span> EmpServiceImpl();</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testAddEmp</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"调用service层的方法添加员工信息..."</span>);</span><br><span class="line">        service.addEmp();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>以上的代码中，<code>EmpController</code>中要调用<code>Service</code>层的方法，所以以new对象的形式获取了<code>EmpService</code>接口子类的实例：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> EmpService service = <span class="keyword">new</span> EmpServiceImpl();</span><br></pre></td></tr></table></figure>

<p>在<code>EmpService</code>的实现类中要调用Dao层的方法，所有通过new对象的形式获取了EmpDao接口子类的实例，代码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> EmpDao dao = <span class="keyword">new</span> EmpDaoImpl();</span><br></pre></td></tr></table></figure>

<p>如果在上面的程序中将<code>EmpDaoImpl</code>或者<code>EmpServiceImpl</code>移除，会导致其他类中的代码编译错误。此时表现层和业务层，及业务层和持久层之间的依赖程度过高，如果将来替换某一层，很可能会造成其他层无法运行，只能通过修改程序代码保证程序运行，这样依赖就会提高维护成本以及造成不必要的麻烦。</p>
<p>而在程序中new对象的方式造成了这种程序之间的依赖程度提升，即提升了程序之间的耦合性。</p>
<p>下面使用工厂+配置文件+接口解耦如下：</p>
<ul>
<li><ol start="6">
<li>创建<code>com.tedu.factory.BeanFactory</code>类，用于创建各个层所需要的对象</li>
</ol>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.tedu.factory;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.InputStream;</span><br><span class="line"><span class="keyword">import</span> java.util.Properties;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * ---------------------------------------------------------</span></span><br><span class="line"><span class="comment"> * Bean: 可重用组件(计算机英语)</span></span><br><span class="line"><span class="comment"> * JavaBean：使用Java语言编写的可重用组件，例如：service层、dao层等</span></span><br><span class="line"><span class="comment"> * JavaBean：通常分为业务Bean和实体Bean</span></span><br><span class="line"><span class="comment"> *         业务Bean：处理业务逻辑，service层、dao层</span></span><br><span class="line"><span class="comment"> *         实体Bean：封装数据，例如，为了封装员工信息而编写的Emp实体类.</span></span><br><span class="line"><span class="comment"> * ---------------------------------------------------------</span></span><br><span class="line"><span class="comment"> * 解除耦合:</span></span><br><span class="line"><span class="comment"> * (1)需要提供配置文件，在配置文件中配置service和dao的实现类</span></span><br><span class="line"><span class="comment"> *         配置内容为：唯一标识=实现类的全限定类名（key=value结构）</span></span><br><span class="line"><span class="comment"> * (2)通过工厂读取配置文件中配置的全限定类名，利用反射创建对象。</span></span><br><span class="line"><span class="comment"> *         xml配置文件、properties配置文件</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BeanFactory</span> </span>&#123;</span><br><span class="line">    <span class="comment">//声明一个Properties对象，在静态代码块中对其进行初始化</span></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> Properties prop;</span><br><span class="line">    <span class="keyword">static</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">//为prop进行实例化</span></span><br><span class="line">            prop = <span class="keyword">new</span> Properties();</span><br><span class="line">            <span class="comment">//获取配置文件的流对象</span></span><br><span class="line">            InputStream in = BeanFactory<span class="class">.<span class="keyword">class</span>.<span class="title">getClassLoader</span>()</span></span><br><span class="line">                    .getResourceAsStream("config.properties");</span><br><span class="line">            <span class="comment">//将配置文件中的内容读取到Properties对象中</span></span><br><span class="line">            prop.load( in );</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> RuntimeException(<span class="string">"初始化Properties对象失败!"</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 根据config.xml文件中的key获取对应class类的实例</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> key</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Object <span class="title">getBean</span><span class="params">(String key)</span> </span>&#123;</span><br><span class="line">        Object bean = <span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            String className = prop.getProperty( key );</span><br><span class="line">            bean = Class.forName(className).newInstance();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> bean;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li><ol start="7">
<li>在源码目录下创建一个<code>config.properties</code>文件，配置如下：</li>
</ol>
</li>
</ul>
<figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">EmpService</span>=<span class="string">com.tedu.service.EmpServiceImpl</span></span><br><span class="line"><span class="attr">EmpDao</span>=<span class="string">com.tedu.dao.EmpDaoImpl</span></span><br></pre></td></tr></table></figure>

<ul>
<li><ol start="8">
<li>将<code>EmpController</code>类中通过”new对象的形式获取了EmpService接口子类的实例”以及在<code>EmpServiceImpl</code>类中通过”new对象的形式获取了EmpDao接口子类的实例”改为使用BeanFactory工厂获取Service和Dao层的实例。</li>
</ol>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 获取Service接口的子类实例</span></span><br><span class="line"><span class="comment"> * ——这里使用new对象的方式造成了程序之间的耦合性提升 */</span></span><br><span class="line"><span class="comment">//private EmpService service = new EmpServiceImpl();</span></span><br><span class="line"><span class="keyword">private</span> EmpService service = (EmpService)BeanFactory.getBean(<span class="string">"EmpService"</span>);</span><br></pre></td></tr></table></figure>

<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 获取Dao接口的子类实例</span></span><br><span class="line"><span class="comment"> * ——这里使用new对象的方式造成了程序之间的耦合性提升 */</span></span><br><span class="line"><span class="comment">//private EmpDao dao = new EmpDaoImpl();</span></span><br><span class="line"><span class="keyword">private</span> EmpDao dao = (EmpDao)BeanFactory.getBean( <span class="string">"EmpDao"</span> );</span><br></pre></td></tr></table></figure>

<h2 id="Spring-IOC控制反转"><a href="#Spring-IOC控制反转" class="headerlink" title="Spring IOC控制反转"></a>Spring IOC控制反转</h2><h3 id="什么是控制反转"><a href="#什么是控制反转" class="headerlink" title="什么是控制反转"></a>什么是控制反转</h3><p>IOC(Inverse Of Control)，控制反转，即把创建对象的权利交给了框架。或者说将对象的创建、存储、管理交给了Spring容器</p>
<p>Spring容器是Spring中的一个核心模块，用于管理对象，底层课理解为一个Map集合</p>
<p><img src="/2020/05/30/Java%E6%97%A5%E6%8B%B1%E4%B8%80%E5%8D%92-day22/IOC.png" alt="IOC"></p>
<p>在此之前，需要对象的时候，通常利用new关键字创建一个对象</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 获取Service接口的子类实例</span></span><br><span class="line"><span class="comment"> * ——这里使用new对象的方式造成了程序之间的耦合性提升 */</span></span><br><span class="line"><span class="keyword">private</span> EmpService service = <span class="keyword">new</span> EmpServiceImpl();</span><br><span class="line"><span class="comment">//private EmpService service = (EmpService)BeanFactory.getBean("EmpService");</span></span><br></pre></td></tr></table></figure>

<p>但是由于new对象会提高类与类之间的依赖关系，即耦合度，而我们现在可以讲对象的创建交给框架来做</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 获取Service接口的子类实例</span></span><br><span class="line"><span class="comment"> * ——这里使用new对象的方式造成了程序之间的耦合性提升 */</span></span><br><span class="line"><span class="comment">//private EmpService service = new EmpServiceImpl();</span></span><br><span class="line"><span class="keyword">private</span> EmpService service = (EmpService)BeanFactory.getBean(<span class="string">"EmpService"</span>);</span><br></pre></td></tr></table></figure>

<p>只需要将类提前配置在配置文件中，就可以将对象的创建交给框架来做。需要对象时，不需要自己创建，而是通过框架获取即可</p>
<h2 id="IOC入门案例"><a href="#IOC入门案例" class="headerlink" title="IOC入门案例"></a>IOC入门案例</h2><p>下面将使用Spring的IOC解决程序之间的耦合：</p>
<h3 id="创建工程，引入jar包"><a href="#创建工程，引入jar包" class="headerlink" title="创建工程，引入jar包"></a>创建工程，引入jar包</h3><ul>
<li><ol>
<li>创建Maven-java工程</li>
</ol>
</li>
<li><ol start="2">
<li>引入<code>junit</code>、<code>Spring</code>的jar包：在Maven工程下的pom.xml的根标签下添加如下配置：</li>
</ol>
</li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dependencies</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 添加junit的jar包 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>junit<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>junit<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>4.10<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 添加spring的jar包 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dependency</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.springframework<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>spring-context<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">version</span>&gt;</span>4.1.3.RELEASE<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dependencies</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h3 id="创建Spring配置文件"><a href="#创建Spring配置文件" class="headerlink" title="创建Spring配置文件"></a>创建Spring配置文件</h3><ul>
<li>1.在src/main/resource下创建applicationContext.xml文件</li>
<li><ol start="2">
<li>将将EmpService接口的实现类的实例以及EmpDao接口的实现类的实例交给Spring容器创建，在核心配置文件中添加如下配置：</li>
</ol>
</li>
</ul>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag">    <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag">    <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans</span></span></span><br><span class="line"><span class="tag"><span class="string">        http://www.springframework.org/schema/beans/spring-beans.xsd"</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- 将EmpService接口的实现类的实例交给spring创建 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"empService"</span> <span class="attr">class</span>=<span class="string">"com.tedu.service.EmpServiceImpl"</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">&lt;!-- 将EmpDao接口的实现类的实例交给spring创建 --&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"empDao"</span> <span class="attr">class</span>=<span class="string">"com.tedu.dao.EmpDaoImpl"</span>&gt;</span><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h3 id="创建测试类进行解耦"><a href="#创建测试类进行解耦" class="headerlink" title="创建测试类进行解耦"></a>创建测试类进行解耦</h3><p>创建测试类TestSpring。通过Spring的IOC进行解耦</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.tedu.spring;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.support.ClassPathXmlApplicationContext;</span><br><span class="line"><span class="keyword">import</span> com.tedu.dao.EmpDao;</span><br><span class="line"><span class="keyword">import</span> com.tedu.service.EmpService;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestSpring</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     *测试spring的IOC</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testIOC</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="comment">//1.获取spring容器对象（读取applicationContext.xml文件）</span></span><br><span class="line">        ClassPathXmlApplicationContext ac =</span><br><span class="line">                <span class="keyword">new</span> ClassPathXmlApplicationContext(<span class="string">"applicationContext.xml"</span>);</span><br><span class="line">        <span class="comment">//2.通过Spring容器获取EmpService层的实例</span></span><br><span class="line">        EmpService service = (EmpService)ac.getBean(<span class="string">"empService"</span>);</span><br><span class="line">        System.out.println(service);</span><br><span class="line">        <span class="comment">//3.通过Spring容器获取EmpDao层的实例</span></span><br><span class="line">        EmpDao dao = (EmpDao) ac.getBean(<span class="string">"empDao"</span>);</span><br><span class="line">        System.out.println(dao);</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="入门案例总价"><a href="#入门案例总价" class="headerlink" title="入门案例总价"></a>入门案例总价</h3><p>这就是spring框架的IOC——控制反转。之前我们自己new对象，例如：</p>
<blockquote>
<p>User u = new User();</p>
</blockquote>
<p>而现在，变成由一个初始化的xml配置文件来创建，也就是由spring容器来创建。</p>
<blockquote>
<p>User user = (User) ac.getBean(“user”);</p>
</blockquote>
<p>当程序运行，spring开始工作后，会加载整个xml核心配置文件，读取到&lt;bean&gt;，获取到class属性中类的全路径，利用反射创建该类的对象。</p>
<h2 id="Bean对象的单例和多例"><a href="#Bean对象的单例和多例" class="headerlink" title="Bean对象的单例和多例"></a>Bean对象的单例和多例</h2><h3 id="Bean对象的单例和多例概述"><a href="#Bean对象的单例和多例概述" class="headerlink" title="Bean对象的单例和多例概述"></a>Bean对象的单例和多例概述</h3><p>在Spring容器中管理的Bean对象的作用域，可以通过<strong>scope属性</strong>或用相关注解指定其作用域。</p>
<p>最常用是singleton（单例）或prototype（多例）。其含义如下：</p>
<ul>
<li><ol>
<li>singleton：单实例，是默认值。这个作用域标识的对象具备全局唯一性。</li>
</ol>
</li>
</ul>
<blockquote>
<p>当把一个 bean 定义设置scope为singleton作用域时，那么Spring IOC容器只会创建该bean定义的唯一实例。也就是说，整个Spring IOC容器中只会创建当前类的唯一一个对象。<br>这个单一实例会被存储到单例缓存（singleton cache）中，并且所有针对该bean的后续请求和引用都 将返回被缓存的、唯一的这个对象实例。<br>singleton负责对象的创建、初始化、销毁。</p>
</blockquote>
<ul>
<li><ol start="2">
<li>prototype：多实例。这个作用域标识的对象每次获取都会创建新的对象。</li>
</ol>
</li>
</ul>
<blockquote>
<p>当把一个 bean 定义设置scope为singleton作用域时，Spring IOC容器会在每一次获取当前Bean时，都会产生一个新的Bean实例（相当于new的操作）<br>prototype只负责对象的创建和初始化，不负责销毁。</p>
</blockquote>

    </div>

    
    
    

      <footer class="post-footer">

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2020/05/22/Java%E6%97%A5%E6%8B%B1%E4%B8%80%E5%8D%92-day21/" rel="prev" title="Java日拱一卒-day21">
      <i class="fa fa-chevron-left"></i> Java日拱一卒-day21
    </a></div>
      <div class="post-nav-item">
    <a href="/2020/06/12/Java%E6%97%A5%E6%8B%B1%E4%B8%80%E5%8D%92-day23/" rel="next" title="Java日拱一卒-day23">
      Java日拱一卒-day23 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#Spring简介"><span class="nav-number">1.</span> <span class="nav-text">Spring简介</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Spring的优势"><span class="nav-number">1.1.</span> <span class="nav-text">Spring的优势</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Spring的架构"><span class="nav-number">1.2.</span> <span class="nav-text">Spring的架构</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#程序中的耦合与解耦"><span class="nav-number">2.</span> <span class="nav-text">程序中的耦合与解耦</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#什么是程序的耦合"><span class="nav-number">2.1.</span> <span class="nav-text">什么是程序的耦合</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#工厂模式解耦示例"><span class="nav-number">2.2.</span> <span class="nav-text">工厂模式解耦示例</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Spring-IOC控制反转"><span class="nav-number">3.</span> <span class="nav-text">Spring IOC控制反转</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#什么是控制反转"><span class="nav-number">3.1.</span> <span class="nav-text">什么是控制反转</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#IOC入门案例"><span class="nav-number">4.</span> <span class="nav-text">IOC入门案例</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#创建工程，引入jar包"><span class="nav-number">4.1.</span> <span class="nav-text">创建工程，引入jar包</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#创建Spring配置文件"><span class="nav-number">4.2.</span> <span class="nav-text">创建Spring配置文件</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#创建测试类进行解耦"><span class="nav-number">4.3.</span> <span class="nav-text">创建测试类进行解耦</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#入门案例总价"><span class="nav-number">4.4.</span> <span class="nav-text">入门案例总价</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Bean对象的单例和多例"><span class="nav-number">5.</span> <span class="nav-text">Bean对象的单例和多例</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#Bean对象的单例和多例概述"><span class="nav-number">5.1.</span> <span class="nav-text">Bean对象的单例和多例概述</span></a></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="文予"
      src="/uploads/wenyu.png">
  <p class="site-author-name" itemprop="name">文予</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">29</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
  </nav>
</div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2020</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">文予</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://pisces.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Pisces</a> 强力驱动
  </div>


        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/pisces.js"></script>


<script src="/js/next-boot.js"></script>




  




  
<script src="/js/local-search.js"></script>











<script>
if (document.querySelectorAll('pre.mermaid').length) {
  NexT.utils.getScript('//cdn.jsdelivr.net/npm/mermaid@8/dist/mermaid.min.js', () => {
    mermaid.initialize({
      theme    : 'forest',
      logLevel : 3,
      flowchart: { curve     : 'linear' },
      gantt    : { axisFormat: '%m/%d/%Y' },
      sequence : { actorMargin: 50 }
    });
  }, window.mermaid);
}
</script>


  

  

</body>
</html>
